home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / xvisrc.zip / EX_CMDS2.C < prev    next >
C/C++ Source or Header  |  1992-07-28  |  7KB  |  345 lines

  1. /* Copyright (c) 1990,1991,1992 Chris and John Downey */
  2. #ifndef lint
  3. static char *sccsid = "@(#)ex_cmds2.c    2.2 (Chris & John Downey) 8/3/92";
  4. #endif
  5.  
  6. /***
  7.  
  8. * program name:
  9.     xvi
  10. * function:
  11.     PD version of UNIX "vi" editor, with extensions.
  12. * module name:
  13.     ex_cmds2.c
  14. * module function:
  15.     Command functions for miscellaneous ex (colon) commands.
  16.     See ex_cmds1.c for file- and buffer-related colon commands.
  17. * history:
  18.     STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  19.     Originally by Tim Thompson (twitch!tjt)
  20.     Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  21.     Heavily modified by Chris & John Downey
  22.  
  23. ***/
  24.  
  25. #include "xvi.h"
  26.  
  27. #ifdef    MEGAMAX
  28. overlay "ex_cmds2"
  29. #endif
  30.  
  31. /*
  32.  * Run shell command.
  33.  *
  34.  * You might think it would be easier to do this as
  35.  *
  36.  *    sys_endv();
  37.  *    system(command);
  38.  *    sys_startv();
  39.  *    prompt("[Hit return to continue] ");
  40.  *    ...
  41.  *
  42.  * but the trouble is that, with some systems, sys_startv() can be
  43.  * used to swap display pages, which would mean that the user would
  44.  * never have time to see the output from the command. (This applies
  45.  * to some terminals, as well as machines with memory-mappped video;
  46.  * cmdtool windows on Sun workstations also do the same thing.)
  47.  *
  48.  * This means we have to display the prompt before calling
  49.  * sys_startv(), so we just use good old fputs(). (We're trying not to
  50.  * use printf()).
  51.  */
  52. /*ARGSUSED*/
  53. void
  54. do_shcmd(window, command)
  55. Xviwin    *window;
  56. char    *command;
  57. {
  58.     int    c;
  59.  
  60.     sys_endv();
  61.  
  62.     (void) fputs(command, stdout);
  63.     (void) fputs("\r\n", stdout);
  64.     (void) fflush(stdout);
  65.     (void) call_system(command);
  66.     (void) fputs("[Hit return to continue] ", stdout);
  67.     (void) fflush(stdout);
  68.     while ((c = getc(stdin)) != '\n' && c != '\r' && c != EOF)
  69.     ;
  70.  
  71.     sys_startv();
  72.     redraw_screen();
  73. }
  74.  
  75. void
  76. do_shell(window)
  77. Xviwin    *window;
  78. {
  79.     char    *sh = NULL;
  80.     int    sysret;
  81.  
  82.     sh = Ps(P_shell);
  83.     if (sh == NULL) {
  84.     show_error(window, "SHELL variable not set");
  85.     return;
  86.     }
  87.  
  88.     sys_endv();
  89.  
  90.     sysret = call_shell(sh);
  91.  
  92.     sys_startv();
  93.     redraw_screen();
  94.  
  95.     if (sysret != 0) {
  96. #ifdef STRERROR_AVAIL
  97.     show_error(window, "Can't execute %s [%s]", sh,
  98.             (errno > 0 ? strerror(errno) : "Unknown Error"));
  99. #else    /* strerror() not available */
  100.     show_error(window, "Can't execute %s", sh);
  101. #endif    /* strerror() not available */
  102.     }
  103. }
  104.  
  105. /*ARGSUSED*/
  106. void
  107. do_suspend(window)
  108. Xviwin    *window;
  109. {
  110.     if (State == NORMAL) {
  111. #    ifdef    SIGSTOP
  112.     extern    int    kill P((int, int));
  113.     extern    int    getpid P((void));
  114.  
  115.     sys_endv();
  116.  
  117.     (void) kill(getpid(), SIGSTOP);
  118.  
  119.     sys_startv();
  120.     redraw_screen();
  121.  
  122. #    else /* SIGSTOP */
  123.  
  124.     /*
  125.      * Can't suspend unless we're on a BSD UNIX system;
  126.      * just pretend by invoking a shell instead.
  127.      */
  128.     do_shell(window);
  129.  
  130. #    endif /* SIGSTOP */
  131.     }
  132. }
  133.  
  134. void
  135. do_equals(window, line)
  136. Xviwin    *window;
  137. Line    *line;
  138. {
  139.     if (line == NULL) {
  140.     /*
  141.      * Default position is ".".
  142.      */
  143.     line = window->w_cursor->p_line;
  144.     }
  145.  
  146.     show_message(window, "Line %ld", lineno(window->w_buffer, line));
  147. }
  148.  
  149. void
  150. do_help(window)
  151. Xviwin    *window;
  152. {
  153.     unsigned    savecho;
  154.  
  155.     savecho = echo;
  156.     echo &= ~(e_SCROLL | e_REPORT | e_SHOWINFO);
  157.     if (Ps(P_helpfile) != NULL && do_buffer(window, Ps(P_helpfile))) {
  158.     /*
  159.      * We use "curbuf" here because the new buffer will
  160.      * have been made the current one by do_buffer().
  161.      */
  162.     curbuf->b_flags |= FL_READONLY | FL_NOEDIT;
  163.     move_window_to_cursor(curwin);
  164.     show_file_info(curwin);
  165.     update_window(curwin);
  166.     }
  167.     echo = savecho;
  168. }
  169.  
  170. bool_t
  171. do_source(interactive, file)
  172. bool_t    interactive;
  173. char    *file;
  174. {
  175.     static char        cmdbuf[256];
  176.     FILE        *fp;
  177.     register int    c;
  178.     register char    *bufp;
  179.     bool_t        literal;
  180.  
  181.     fp = fopen(file, "r");
  182.     if (fp == NULL) {
  183.     if (interactive) {
  184.         show_error(curwin, "Can't open \"%s\"", file);
  185.     }
  186.     return(FALSE);
  187.     }
  188.  
  189.     bufp = cmdbuf;
  190.     literal = FALSE;
  191.     while ((c = getc(fp)) != EOF) {
  192.     if (!literal && (c == CTRL('V') || c == '\n')) {
  193.         switch (c) {
  194.         case CTRL('V'):
  195.         literal = TRUE;
  196.         break;
  197.  
  198.         case '\n':
  199.         if (kbdintr) {
  200.             imessage = TRUE;
  201.             break;
  202.         }
  203.         if (bufp > cmdbuf) {
  204.             *bufp = '\0';
  205.             do_colon(cmdbuf, FALSE);
  206.         }
  207.         bufp = cmdbuf;
  208.         break;
  209.         }
  210.     } else {
  211.         literal = FALSE;
  212.         if (bufp < &cmdbuf[sizeof(cmdbuf) - 1]) {
  213.         *bufp++ = c;
  214.         }
  215.     }
  216.     }
  217.     (void) fclose(fp);
  218.     return(TRUE);
  219. }
  220.  
  221. /*
  222.  * Change directory.
  223.  *
  224.  * With a NULL argument, change to the directory given by the HOME
  225.  * environment variable if it is defined; with an argument of "-",
  226.  * change back to the previous directory (like ksh).
  227.  *
  228.  * Return NULL pointer if OK, otherwise error message to say
  229.  * what went wrong.
  230.  */
  231. char *
  232. do_chdir(dir)
  233.     char    *dir;
  234. {
  235.     static char    *homedir = NULL;
  236.     static char    *prevdir = NULL;
  237.     char    *ret;
  238.     char    *curdir;
  239.  
  240.     if (dir == NULL && homedir == NULL &&
  241.                     (homedir = getenv("HOME")) == NULL) {
  242.     return("HOME environment variable not set");
  243.     }
  244.  
  245.     if (dir == NULL) {
  246.     dir = homedir;
  247.     } else if (*dir == '-' && dir[1] == '\0') {
  248.     if (prevdir == NULL) {
  249.         return("No previous directory");
  250.     } else {
  251.         dir = prevdir;
  252.     }
  253.     }
  254.  
  255.     curdir = malloc(MAXPATHLEN + 2);
  256.     if (curdir != NULL && getcwd(curdir, MAXPATHLEN + 2) == NULL) {
  257.     free(curdir);
  258.     curdir = NULL;
  259.     }
  260.     ret = (chdir(dir) == 0 ? NULL : "Invalid directory");
  261.     if (prevdir) {
  262.     free(prevdir);
  263.     prevdir = NULL;
  264.     }
  265.     if (curdir) {
  266.     prevdir = realloc(curdir, (unsigned) strlen(curdir) + 1);
  267.     }
  268.     return(ret);
  269. }
  270.  
  271. void
  272. do_cdmy(type, l1, l2, destline)
  273. int    type;            /* one of [cdmy] */
  274. Line    *l1, *l2;        /* start and end (inclusive) of range */
  275. Line    *destline;        /* destination line for copy/move */
  276. {
  277.     Posn    p1, p2;
  278.     Posn    destpos;
  279.  
  280.     p1.p_line = (l1 != NULL) ? l1 : curwin->w_cursor->p_line;
  281.     p2.p_line = (l2 != NULL) ? l2 : p1.p_line;
  282.     p1.p_index = p2.p_index = 0;
  283.  
  284.     if (type == 'c' || type == 'm') {
  285.     if (destline == NULL) {
  286.         show_error(curwin, "No destination specified");
  287.         return;
  288.     }
  289.     }
  290.  
  291.     /*
  292.      * Check that the destination is not inside
  293.      * the source range for "move" operations.
  294.      */
  295.     if (type == 'm') {
  296.     unsigned long    destlineno;
  297.  
  298.     destlineno = lineno(curbuf, destline);
  299.     if (destlineno >= lineno(curbuf, p1.p_line) &&
  300.                 destlineno <= lineno(curbuf, p2.p_line)) {
  301.         show_error(curwin, "Source conflicts with destination of move");
  302.         return;
  303.     }
  304.     }
  305.  
  306.     /*
  307.      * Yank the text to be copied.
  308.      */
  309.     if (do_yank(curbuf, &p1, &p2, FALSE, '@') == FALSE) {
  310.     show_error(curwin, "Not enough memory to yank text");
  311.     return;
  312.     }
  313.  
  314.     if (!start_command(curwin)) {
  315.     return;
  316.     }
  317.  
  318.     switch (type) {
  319.     case 'd':            /* delete */
  320.     case 'm':            /* move */
  321.     move_cursor(curwin, p1.p_line, 0);
  322.     repllines(curwin, p1.p_line, cntllines(p1.p_line, p2.p_line),
  323.                         (Line *) NULL);
  324.     update_buffer(curbuf);
  325.     cursupdate(curwin);
  326.     begin_line(curwin, TRUE);
  327.     }
  328.  
  329.     switch (type) {
  330.     case 'c':            /* copy */
  331.     case 'm':            /* move */
  332.     /*
  333.      * And put it back at the destination point.
  334.      */
  335.     destpos.p_line = destline;
  336.     destpos.p_index = 0;
  337.     do_put(curwin, &destpos, FORWARD, '@');
  338.  
  339.     update_buffer(curbuf);
  340.     cursupdate(curwin);
  341.     }
  342.  
  343.     end_command(curwin);
  344. }
  345.